package com.spider.admin.service.agent;

import com.spider.admin.agent.conf.CommonConf;
import com.spider.admin.conf.ENVConf;
import com.spider.admin.conf.ResultMessage;
import com.spider.admin.conf.StructVar;
import com.spider.admin.exception.SpiderException;
import com.spider.admin.http.entity.PageResult;
import com.spider.admin.store.primary.mapper.AgentConfMapper;
import com.spider.admin.store.primary.mapper.AgentSettingMapper;
import com.spider.admin.store.primary.mapper.AppMapper;
import com.spider.admin.store.primary.mapper.CloudMapper;
import com.spider.admin.store.primary.model.*;
import com.spider.admin.utils.CommonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class AgentConfServiceImpl implements AgentConfService {

    @Autowired
    private AgentConfMapper agentConfMapper;

    @Autowired
    private AgentSettingMapper agentSettingMapper;

    @Autowired
    private ENVConf envConf;

    @Override
    public PageResult<AgentConf> queryConfList(Integer page, Integer pageSize, String confType, String belongId, String confVersion, Date updateTime) throws SpiderException {
        try {
            page = page == null || page.intValue() <= 0 ? 1 : page;
            pageSize = pageSize == null ? 10 : pageSize;
            Date startUpdateTime = null;
            Date endUpdateTime = null;
            if (updateTime != null) {
                //创建日期格式对象
                SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
                //日期转换为字符串
                String str = s.format(updateTime);

                SimpleDateFormat csf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                startUpdateTime = csf.parse(str + " 00:00:00");
                endUpdateTime = csf.parse(str + " 23:59:59");
            }
            long totalCount = 0;
            List<AgentConf> records = null;
            int totalPage = 0;
            switch (confType) {
                case StructVar.AGENT_CONF_TYPE_SERVER:
                    totalCount = agentConfMapper.queryAgentConfListCount(confType, belongId, null, confVersion, startUpdateTime, endUpdateTime).longValue();
                    totalPage = (int) Math.ceil((double) totalCount / (double) pageSize);
                    page = page > totalPage ? totalPage : page;
                    page = page <= 0 ? 1 : page;
                    records = agentConfMapper.queryAgentConfList((page - 1) * pageSize, pageSize, confType, belongId, null, confVersion, startUpdateTime, endUpdateTime);
                    break;
                case StructVar.AGENT_CONF_TYPE_LOCATION:
                    totalCount = agentConfMapper.queryAgentConfListCount(confType, null, belongId, confVersion, startUpdateTime, endUpdateTime).longValue();
                    totalPage = (int) Math.ceil((double) totalCount / (double) pageSize);
                    page = page > totalPage ? totalPage : page;
                    page = page <= 0 ? 1 : page;
                    records = agentConfMapper.queryAgentConfList((page - 1) * pageSize, pageSize, confType, null, belongId, confVersion, startUpdateTime, endUpdateTime);
                    break;
                case StructVar.AGENT_CONF_TYPE_GLOBAL:
                    totalCount = agentConfMapper.queryAgentConfListCount(confType, null, null, confVersion, startUpdateTime, endUpdateTime).longValue();
                    totalPage = (int) Math.ceil((double) totalCount / (double) pageSize);
                    page = page > totalPage ? totalPage : page;
                    page = page <= 0 ? 1 : page;
                    records = agentConfMapper.queryAgentConfList((page - 1) * pageSize, pageSize, confType, null, null, confVersion, startUpdateTime, endUpdateTime);
                default:
            }

            PageResult<AgentConf> result = new PageResult<>();
            result.setCurrentPage(page);
            result.setPageSize(pageSize);
            result.setTotal(totalCount);
            result.setTotalPage(totalPage);
            result.setList(records == null ? new ArrayList<>() : records);

            return result;
        } catch (Exception e) {
            throw new SpiderException(ResultMessage.FAILED.getCode(), "查询处理异常：" + e.getMessage());
        }
    }

    @Override
    public PageResult<AgentConf> queryRunConfList(Integer page, Integer pageSize, String confType, String belongId, String confVersion, Date updateTime) throws SpiderException {
        try {
            page = page == null || page.intValue() <= 0 ? 1 : page;
            pageSize = pageSize == null ? 10 : pageSize;
            Date startUpdateTime = null;
            Date endUpdateTime = null;
            if (updateTime != null) {
                //创建日期格式对象
                SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
                //日期转换为字符串
                String str = s.format(updateTime);

                SimpleDateFormat csf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                startUpdateTime = csf.parse(str + " 00:00:00");
                endUpdateTime = csf.parse(str + " 23:59:59");
            }
            long totalCount = 0;
            List<AgentConf> records = null;
            int totalPage = 0;
            switch (confType) {
                case StructVar.AGENT_CONF_TYPE_SERVER:
                    totalCount = agentConfMapper.queryRunAgentConfListCount(confType, belongId, null, confVersion, startUpdateTime, endUpdateTime).longValue();
                    totalPage = (int) Math.ceil((double) totalCount / (double) pageSize);
                    page = page > totalPage ? totalPage : page;
                    page = page <= 0 ? 1 : page;
                    records = agentConfMapper.queryRunAgentConfList((page - 1) * pageSize, pageSize, confType, belongId, null, confVersion, startUpdateTime, endUpdateTime);
                    break;
                case StructVar.AGENT_CONF_TYPE_LOCATION:
                    totalCount = agentConfMapper.queryRunAgentConfListCount(confType, null, belongId, confVersion, startUpdateTime, endUpdateTime).longValue();
                    totalPage = (int) Math.ceil((double) totalCount / (double) pageSize);
                    page = page > totalPage ? totalPage : page;
                    page = page <= 0 ? 1 : page;
                    records = agentConfMapper.queryRunAgentConfList((page - 1) * pageSize, pageSize, confType, null, belongId, confVersion, startUpdateTime, endUpdateTime);
                    break;
                case StructVar.AGENT_CONF_TYPE_GLOBAL:
                    totalCount = agentConfMapper.queryRunAgentConfListCount(confType, null, null, confVersion, startUpdateTime, endUpdateTime).longValue();
                    totalPage = (int) Math.ceil((double) totalCount / (double) pageSize);
                    page = page > totalPage ? totalPage : page;
                    page = page <= 0 ? 1 : page;
                    records = agentConfMapper.queryRunAgentConfList((page - 1) * pageSize, pageSize, confType, null, null, confVersion, startUpdateTime, endUpdateTime);
                    break;
                default:
                    break;
            }

            PageResult<AgentConf> result = new PageResult<>();
            result.setCurrentPage(page);
            result.setPageSize(pageSize);
            result.setTotal(totalCount);
            result.setTotalPage(totalPage);
            result.setList(records == null ? new ArrayList<>() : records);

            return result;
        } catch (Exception e) {
            throw new SpiderException(ResultMessage.FAILED.getCode(), "查询处理异常：" + e.getMessage());
        }
    }

    @Override
    public String createGlobalConfContext() throws SpiderException {
        String version = "";
        List<AgentSettingInfo> result = agentSettingMapper.queryGlobalAgentConfList();
        String globalConfContext = "";
        String eventsConfContext = "";
        String httpConfContext = "";
        version = "GV" + (new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        if (result != null && !result.isEmpty()) {
            for (AgentSettingInfo agentSetting : result) {
                if (StringUtils.isNotEmpty(agentSetting.getOptionValue())) {
                    switch (agentSetting.getSection()) {
                        case "global":
                            globalConfContext = globalConfContext + agentSetting.getOptionItem() + "\t" + agentSetting.getOptionValue() +
                                    ";\t#" + (StringUtils.isEmpty(agentSetting.getSettingDesc()) ? "" : agentSetting.getSettingDesc()) + "\n";
                            break;
                        case "events":
                            eventsConfContext = eventsConfContext + "\t" + agentSetting.getOptionItem() + "\t" + agentSetting.getOptionValue() +
                                    ";\t#" + (StringUtils.isEmpty(agentSetting.getSettingDesc()) ? "" : agentSetting.getSettingDesc()) + "\n";
                            break;
                        case "http":
                            httpConfContext = httpConfContext + "\t" + agentSetting.getOptionItem() + "\t" + agentSetting.getOptionValue() +
                                    ";\t#" + (StringUtils.isEmpty(agentSetting.getSettingDesc()) ? "" : agentSetting.getSettingDesc()) + "\n";
                            break;
                        default:
                            break;
                    }
                }
            }
        }
        httpConfContext = httpConfContext + "\tlua_shared_dict logs_data 1m;\n" +
                "\tinit_worker_by_lua_file hgg-lua/timer.lua;\n" +
                "\tinclude ../spider_conf/server-pro/*.conf;\n";
        String confContext = globalConfContext + "\n\n\nevents {\n" + eventsConfContext + "}\n\n\nhttp {\n" + httpConfContext + "}";
//            log.info(confContext);
        AgentConf agentConf = new AgentConf();
        agentConf.setConfContext(confContext);
        agentConf.setPid(CommonUtil.getUniqueKey());
        agentConf.setConfStatus(StructVar.AGENT_CONF_CONTEXT_STATUS_INIT);
        agentConf.setConfType(StructVar.AGENT_CONF_TYPE_GLOBAL);
        agentConf.setConfVersion(version);
        agentConfMapper.insertConfContext(agentConf);
        return version;
    }

    @Autowired
    private CloudMapper cloudMapper;

    @Override
    public String createServerConfContext(String serverId) throws SpiderException {
        String version = "";
        List<AgentSettingInfo> result = agentSettingMapper.queryServerAgentConfList(serverId);
        String serverConfContext = "";
        CloudInfo cloudInfo = cloudMapper.getActiveCloudById(serverId);
        if (cloudInfo == null) {
            throw new SpiderException(ResultMessage.FAILED_PARAMS_VALIDATE.getCode(), "服务云不存在或未激活，不能生成代理配置");
        }
        version = "CLS" + (new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        if (result != null && !result.isEmpty()) {

            for (AgentSettingInfo agentSetting : result) {
                if (StringUtils.isNotEmpty(agentSetting.getOptionValue())) {
                    serverConfContext = serverConfContext + agentSetting.getOptionItem() + "\t" + agentSetting.getOptionValue() +
                            ";\t#" + (StringUtils.isEmpty(agentSetting.getSettingDesc()) ? "" : agentSetting.getSettingDesc()) + "\n";
                }
            }
        }
        serverConfContext = "server {\n" +
                "    listen       " + envConf.getAgentRunPort() + ";\n" +
                "    server_name  " + cloudInfo.getCloudBasePath() + ";\n" +
                serverConfContext +
                "\n" + CommonConf.getCommonConfInfo(envConf.getServerContextPath(), envConf.getServerPort()) +
                "    \n" +
                "}";

//            log.info(confContext);
        AgentConf agentConf = new AgentConf();
        agentConf.setConfContext(serverConfContext);
        agentConf.setPid(CommonUtil.getUniqueKey());
        agentConf.setBelongServerId(serverId);
        agentConf.setConfStatus(StructVar.AGENT_CONF_CONTEXT_STATUS_INIT);
        agentConf.setConfType(StructVar.AGENT_CONF_TYPE_SERVER);
        agentConf.setConfVersion(version);
        agentConfMapper.insertConfContext(agentConf);
        return version;
    }

    @Autowired
    private AppMapper appMapper;

    @Override
    public String createAppConfContext(String appId) throws SpiderException {
        String version = "";
        List<AgentSettingInfo> result = agentSettingMapper.queryAppAgentConfList(appId);
        AppInfo appInfo = appMapper.queryActiveAppById(appId);
        if (appInfo == null) {
            throw new SpiderException(ResultMessage.FAILED_PARAMS_VALIDATE.getCode(), "应用不存在或未激活，不能生成代理配置");
        }
        String[] adds = StringUtils.isEmpty(appInfo.getAppOriginalUrl()) ? null : appInfo.getAppOriginalUrl().split(";");
        if (adds == null || adds.length <= 0) {
            throw new SpiderException(ResultMessage.FAILED_PARAMS_VALIDATE.getCode(), "应用源地址为空，不能生成代理配置");
        }
        String locationConfContext = "";
        version = "LOC" + (new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        if (result != null && !result.isEmpty()) {
            for (AgentSettingInfo agentSetting : result) {
                if (StringUtils.isNotEmpty(agentSetting.getOptionValue())) {
                    locationConfContext = locationConfContext + agentSetting.getOptionItem() + "\t" + agentSetting.getOptionValue() +
                            ";\t#" + (StringUtils.isEmpty(agentSetting.getSettingDesc()) ? "" : agentSetting.getSettingDesc()) + "\n";
                }
            }
        }

        String upStreamContext = "upstream " + version + " {\n";
        String rh = "http://";

        for (String add : adds) {
            if (add.startsWith("https://")) {
                rh = "https://";
            }
            upStreamContext = upStreamContext + "    server " + add.replace(rh, "") + ";\n";
        }
        upStreamContext = upStreamContext + "}";

        locationConfContext = "location " + appInfo.getAppUrl() + " {\n" +
                locationConfContext +
                "        proxy_pass   " + rh + version + ";\n" +
                "    }";

        String confContext = upStreamContext + "\n\n" + locationConfContext;
//            log.info(confContext);
        AgentConf agentConf = new AgentConf();
        agentConf.setConfContext(confContext);
        agentConf.setPid(CommonUtil.getUniqueKey());
        agentConf.setBelongAppId(appId);
        agentConf.setConfStatus(StructVar.AGENT_CONF_CONTEXT_STATUS_INIT);
        agentConf.setConfType(StructVar.AGENT_CONF_TYPE_LOCATION);
        agentConf.setConfVersion(version);
        agentConfMapper.insertConfContext(agentConf);
        return version;
    }

    @Override
    public int deleteAgentConf(String confId) throws SpiderException {
        return agentConfMapper.delAgentConf(confId);
    }

    @Override
    public int updateAgentConfStatus(String confId, int confStatus) throws SpiderException {
        return agentConfMapper.updateConfStatus(confId,confStatus);
    }

}
